require 'sketchup.rb'
require File.join(__FILE__, '../amtf_mixin.rb')
require 'json'
# require 'open3'
# require 'win32ole'
module AMTF
  class A导出
    include AMTF_mixin

    def 另存skp放平炸开重组组件_导出组件定义到单独文件(每块板数)
      设置常用对象
      if @selection.count == 0
        entities = @model.active_entities
      else
        entities=@selection
      end
      拟导出组名数组=[]
      拟导出全名hash=Hash[]
      @拟导出组s=[]
      @处理完成组s=[]
      拟删除es=[]
      #先判断有没有重名组件
      entities.each {|e|
        if e.is_a? Sketchup::ComponentInstance or e.is_a? Sketchup::Group
          拟导出组名=e.name
          关键词位置= 拟导出组名=~ /参考|布局盒子/i
          puts "关键词位置:"
          puts 关键词位置
          if 关键词位置!=nil
            puts "拟排除群组"
            puts 拟导出组名
            next
            puts "看到我说明上面的next没有奏效！"
          end

          if 拟导出组名数组.include?(拟导出组名)
            UI.messagebox "有 重名 的组件: #{拟导出组名}   !  \n 请修改！"
            return
          else
            匹配编号=/__(\d+)./.match(拟导出组名)
            if 匹配编号==nil
              # UI.messagebox "组件 #{拟导出组名} 还没有 ABF编号 信息!  \n 请先添加！"
              puts "匹配编号==nil"
              puts e
              # return
            else
              puts "拟导出组名数组.push 拟导出组名"
              拟导出组名数组.push 拟导出组名
              # e.visible=false
              @拟导出组s.push e
              puts 拟导出组名
            end
          end
        end #if e.is_a? Sketchup::Group
      }

      if 拟导出组名数组.count==0
        UI.messagebox "没有符合要求的群组可以导出!  \n 是不是，没有全部添加ABF标签？"
        return
      end

      显示不能隐藏的层()

      model = Sketchup.active_model
      entities = model.active_entities
      # amtf.nil
      for e in entities do
        if e.is_a? Sketchup::ComponentInstance or e.is_a? Sketchup::Group
          if !@拟导出组s.include?(e)
            拟删除es.push e
          end
        end
      end
      for 拟删除e in 拟删除es do
        拟删除e.erase!
      end

      @导出路径=生成导出文件夹()

      model = Sketchup.active_model
      file=model.path
      文件名 = File.basename(file, '.*')
      另存文件名=文件名
      另存文件名=另存文件名+'_另存文件_摆正'
      总另存全名=@导出路径+'/'+另存文件名+'.skp'
      puts "总另存全名"
      puts 总另存全名
      status = model.save(总另存全名)

      model = Sketchup.active_model
      entities = model.entities

      拟导出全名hash=Hash[]
      i=0
      @拟导出组s.each {|俯视group1|
        puts "拟处理组件"
        puts 俯视group1.name
        # 俯视group1.visible=true
        原组件名=俯视group1.name
        删除参考线(俯视group1)

        俯视group1=板材躺平(俯视group1)
        导出全名=导出组件定义到单独文件(俯视group1,每块板数)
        拟导出全名hash[导出全名]=""
        # model=生成视图(俯视group1)

        # group=零散元素成组
        # @处理完成组s.push group
        i=i+1
        发送提示信息("处理完第 #{i} 一个")
      }

      model.save
      return 拟导出全名hash,@导出路径
    end#def

    def 导出组件定义到单独文件(拟导出对象,每块板数)
      材质名称=获取组件面材质名称(拟导出对象)
      # 产品-柜名_成品名称_纹理(1=横纹)_柜号1_柜号2_数量_-1(不知道什么含义)_订单_客户_材质
      组件实例名=拟导出对象.name

      # __88. 衣柜-层板#150
      puts "组件实例名:"
      puts 组件实例名
      kk=/__(\d+)./.match(组件实例名)
      编号=kk[1]
      去除编号=组件实例名.sub!(/__(\d+). /, "")
      去除编号sp=去除编号.split("_")
      # 产品=去除编号sp[0].split("-")[0]
      # 柜名=去除编号sp[0].split("-")[1]
      # 成品名称=去除编号sp[1]
      纹理=1#(1=横纹)
      柜号1=编号
      柜号2="00"
      数量=每块板数
      # 订单=去除编号sp[1]
      # 客户=去除编号sp[2]
      材质=材质名称
      关键词位置= 材质=~ /\([\s\S]+\)/i
      if 关键词位置==nil
        puts "材质:"
        材质="默认板材(#{材质})"
        puts 材质
      end

      成品柜名=去除编号sp[0]
      单元柜名=去除编号sp[1]
      板名=去除编号sp[2]
      订单=去除编号sp[3]
      客户=去除编号sp[4]

      @开料主信息="#{成品柜名}-#{单元柜名}_#{板名}_#{纹理}_#{柜号1}_#{柜号2}_#{数量}_-1_#{订单}_#{客户}_#{材质}"
      # @开料主信息=@开料主信息+时间后缀
      # puts @导出路径
      # puts @开料主信息

      导出全名=@导出路径+'/'+@开料主信息+'.skp'

      # Sketchup.file_new
      # Sketchup.active_model.save 导出全名
      definitions = @model.definitions
      # componentdefinition = definitions.add "临时包裹组件"
      # ents = componentdefinition.entities
      # ents.add_group(*拟导出对象.entities)

      definition = 拟导出对象.definition

      # amtf.nil
      发送提示信息("正在 另存组件：#{组件实例名}" )
      kk=definition.save_as(导出全名)
      return 导出全名
    end

    def 拼合组件名(收到的组件名)
      设置常用对象
      if @selection.count == 0
        entities = @model.active_entities
      else
        entities=@selection
      end
      收到的组件名sp=收到的组件名.split("_")
      entities.each {|e|
        if e.is_a? Sketchup::ComponentInstance or e.is_a? Sketchup::Group
          组件实例名=e.name
          puts "组件实例名:"+组件实例名
          # __88. 衣柜-层板#150
          kk=/(__\d+. )/.match(组件实例名)
          编号=kk[1]
          puts "编号："
          puts 编号

          去除编号=组件实例名.sub!(/__(\d+). /, "")
          去除编号sp=去除编号.split("_")
          puts "去除编号sp:"
          puts 去除编号sp
          puts 去除编号sp[2]==nil
          if 去除编号sp[2]!=nil
            板名=去除编号sp[2]
          else
            板名=去除编号sp[0]
          end
          puts "板名："
          puts 板名
          收到的组件名sp[2]=板名
          puts "收到的组件名sp"
          puts 收到的组件名sp
          新组件名=收到的组件名sp.join('_')
          新组件名=编号+新组件名
          puts 新组件名
          e.name=新组件名
        end
      }
    end

    def 解读组件名
      设置常用对象
      if @selection.count == 0
        entities = @model.active_entities
      else
        entities=@selection
      end
      成品柜名=""
      单元柜名=""
      板名=""
      订单=""
      客户=""
      entities.each {|e|
        if e.is_a? Sketchup::ComponentInstance or e.is_a? Sketchup::Group
          组件实例名=e.name
          puts "组件实例名:"+组件实例名
          # __88. 衣柜-层板#150
          # kk=/__(\d+)./.match(组件实例名)
          # 编号=kk[1]
          去除编号=组件实例名.sub!(/__(\d+). /, "")
          去除编号sp=去除编号.split("_")
          puts 去除编号sp.count
          puts "去除编号sp[2]:"
          puts 去除编号sp[2]
          puts 去除编号sp[2]==nil
          if 去除编号sp.count==1
            板名=去除编号sp[0]
            puts "板名:"+板名
          else
            if 成品柜名 == ""
              成品柜名=去除编号sp[0]
            end
            if 单元柜名 == ""
              单元柜名=去除编号sp[1]
            end
            if 板名 == ""
              板名=去除编号sp[2]
            end
            if 订单 == ""
              订单=去除编号sp[3]
            end
            if 客户 == ""
              客户=去除编号sp[4]
            end
            if 成品柜名 != "" and 单元柜名 != "" and 板名 != "" and 订单 != "" and 客户 != ""
              break
            end
          end
        end
      }
      解读后的组件名="#{成品柜名}_#{单元柜名}_#{板名}_#{订单}_#{客户}"
      puts "解读后的组件名:"+解读后的组件名
      return 解读后的组件名
    end

    def 显示不能隐藏的层
      # 门板层不能隐藏，不然后面会有问题
      model = Sketchup.active_model
      layers = model.layers
      layer_by_name = layers["afu-门板"]
      if layer_by_name != nil
        if !layer_by_name.visible?
          layer_by_name.visible=true
          model.save
        end
      end

    end

    def 导出dxf(导出全名)
      puts "打开导出文件: #{导出全名}"
      # 拟导出对象=打开导出文件躺平处理(导出全名,原缩放大小)

      result = Sketchup.open_file(导出全名)
      # puts "打开导出文件result:#{result}"
      发送提示信息("正在 打开导出的组件：#{导出全名}" )

      result = Sketchup.send_action("viewIso:")
      result = Sketchup.send_action("viewZoomExtents:")
      entities1 = Sketchup.active_model.active_entities
      俯视group1 = entities1.add_group(entities1.to_a)

      # amtf.nil
      model=生成视图(俯视group1)
      导出dxf全名=导出dxf_主体(model)
      板厚mm=(@板厚*25.4).round(1)

      return 导出dxf全名,板厚mm
      # 拟导出全名_dxfhash[导出全名]=导出dxf全名
    end

    def 文字测试()
            # text=拟导出对象
      # puts 拟导出对象.has_leader?
      # puts text.display_leader?
      # puts text.leader_type
    end
    def 导出cad测试
      导出dxf(Sketchup.active_model)
    end

    def 导出dxf_主体(m)
      m.save
      file=m.path
      路径 = File.dirname(file).freeze
      文件名 = File.basename(file, '.*')
      # today = Time.new;
      # 时间后缀= today.strftime("%Y%m%d_%H%M%S");

      # # @开料主信息=文件名
      # # @开料主信息=@开料主信息+时间后缀

      # @导出路径="#{路径}"
      # # 导出全名=@导出路径+'/'+@开料主信息+'.dxf'
      板厚mm=(@板厚*25.4).round(0)
      导出dxf全名="#{路径}/#{文件名}.dxf"

      options_hash = {:acad_version=> "acad_2000",
        :edges => true,
        :faces_flag  => false,
        :construction_geometry  => false,
        :dimensions   => false,
        :texture_maps => false,
        :text => false}
      status = m.export(导出dxf全名, options_hash)
      if !status
        发送提示信息("导出DXF出错了……" )
      else
        发送提示信息("顺利导出文件 ：#{导出dxf全名}……" )
        # 拟导出全名_dxfhash[file]=导出dxf全名
        return 导出dxf全名
      end
    end
    def 生成视图测试(c)
      生成视图(c)
    end
    def 生成视图(c)
      视图间距 ||= 40.mm
      # prompts = ["输入视图间距"]
        trr = c.transformation
        # 边界=获取边界大小(c)
        边界=获取边界大小排除部分组件(c,/_ABF_Intersect|_ABF_Label/i)
        bounds=边界[3]
        # puts "trr.origin:\t#{trr.origin}"
        # puts "bounds.corner(0):\t#{bounds.corner(0).transform! trr}"
        # puts "bounds.corner(4):\t#{bounds.corner(4).transform! trr}"
        左前上角=bounds.corner(4).transform! trr
        point2 = Geom::Point3d.new(0,0,0)
        vector = 左前上角.vector_to(point2)
        tr  = Geom::Transformation.new(vector)
        c.transform! tr

        trr = c.transformation
        # 边界=获取边界大小(c)
        边界=获取边界大小排除部分组件(c,/_ABF_Intersect|_ABF_Label/i)
        bounds=边界[3]
        # puts "trr.origin:\t#{trr.origin}"
        # puts "bounds.corner(0):\t#{bounds.corner(0).transform! trr}"
        # puts "bounds.corner(4):\t#{bounds.corner(4).transform! trr}"
        左前上角=bounds.corner(4).transform! trr
        板宽=边界[0]
        板高=边界[1]
        @板厚=边界[2]
        # puts "@板厚:\t#{@板厚}"

        parent = c.parent
        左视组件=parent.entities.add_instance(c.definition,trr)
        # amtf.nil
        # 左视组件=Sketchup.active_model.entities.add_instance(c.definition,trr)
        左视组件.make_unique
        # point = Geom::Point3d.new(trr.origin.x, 0, 0)
        point = 左前上角
        rot = Geom::Transformation.rotation(point,Y_AXIS,90.degrees)
        左视组件.transform! rot
        vector = Geom::Vector3d.new(视图间距+板宽+@板厚, 0, 0)
        tr  = Geom::Transformation.new(vector)
        左视组件.transform! tr
        # amtf.nil

        右视组件=parent.entities.add_instance(c.definition,trr)
        # 右视组件=Sketchup.active_model.entities.add_instance(c.definition,trr)
        右视组件.make_unique
        point = Geom::Point3d.new(板宽, 0, 0)
        rot = Geom::Transformation.rotation(point,Y_AXIS,-90.degrees)
        右视组件.transform! rot
        vector = Geom::Vector3d.new(-视图间距-板宽-@板厚, 0, 0)
        tr  = Geom::Transformation.new(vector)
        右视组件.transform! tr
        # amtf.nil

        后视组件=parent.entities.add_instance(c.definition,trr)
        # 后视组件=Sketchup.active_model.entities.add_instance(c.definition,trr)
        后视组件.make_unique
        point = Geom::Point3d.new(板宽/2, 0, -@板厚/2)
        rot = Geom::Transformation.rotation(point,Y_AXIS,180.degrees)
        后视组件.transform! rot
        vector = Geom::Vector3d.new(板宽+视图间距+@板厚+视图间距, 0, 0)
        tr  = Geom::Transformation.new(vector)
        后视组件.transform! tr

        上视组件=parent.entities.add_instance(c.definition,trr)
        # 上视组件=Sketchup.active_model.entities.add_instance(c.definition,trr)
        上视组件.make_unique
        point = Geom::Point3d.new(0, 板高, 0)
        rot = Geom::Transformation.rotation(point,X_AXIS,90.degrees)
        上视组件.transform! rot
        vector = Geom::Vector3d.new(0, -板高-视图间距-@板厚, 0)
        tr  = Geom::Transformation.new(vector)
        上视组件.transform! tr

        下视组件=parent.entities.add_instance(c.definition,trr)
        # 下视组件=Sketchup.active_model.entities.add_instance(c.definition,trr)
        下视组件.make_unique
        point =左前上角
        rot = Geom::Transformation.rotation(point,X_AXIS,-90.degrees)
        下视组件.transform! rot
        vector = Geom::Vector3d.new(0, 板高+视图间距+@板厚, 0)
        tr  = Geom::Transformation.new(vector)
        下视组件.transform! tr

        保留顶面_删除其他边(c)
        删除非顶面群组(c,true)
        处理图层(c,'0',"red")
        # amtf.nil

        添加轮廓面_删除其他边(左视组件,0,2,6,4)
        删除非顶面群组(左视组件,false)
        处理图层(左视组件,'3',"white")

        添加轮廓面_删除其他边(右视组件,1,3,7,5)
        删除非顶面群组(右视组件,false)
        处理图层(右视组件,'2',"white")

        保留顶面_删除其他边(后视组件)
        删除非顶面群组(后视组件,true)
        处理图层(后视组件,'1',"red")
        # amtf.nil


        添加轮廓面_删除其他边(上视组件,2,3,7,6)
        删除非顶面群组(上视组件,false)
        处理图层(上视组件,'4',"white")

        添加轮廓面_删除其他边(下视组件,0,1,5,4)
        删除非顶面群组(下视组件,false)
        处理图层(下视组件,'5',"white")

        model = Sketchup.active_model
        # 复制面出来删除其他可能的多余边线(model)
        # amtf.nil
        子群组炸开处理_顶层面内部边界处理(parent)
        # 子群组炸开处理_顶层面内部边界处理(model)

        # amtf.nil
        return model
        # 试图输入 屏幕文字，以导出到cad,奈何没做到👇
        # entities = model.entities
        # point = Geom::Point3d.new(trr.origin)
        # # ipt = Sketchup::InputPoint.new(point)
        # ipt = Sketchup::InputPoint.new
        # puts ipt.x
        # amtf.nil
        # # point = Geom::Point3d.new(trr.origin.x, trr.origin.y, 20)
        # text = entities.add_text "地柜_左侧板_1_左侧板_15797_1_0___枫木",ipt,Geom::Vector3d.new(1, 0, 0)
        # layers = model.layers
        # new_layer = layers.add('TextToNest')
        # text.layer = new_layer
        # text.display_leader=false
        # text.leader_type=0
    end

    def 添加轮廓面_删除其他边(c,一,二,三,四)
      model = Sketchup.active_model
      selection = model.selection
      entities=c.entities
      # 边界=获取边界大小(c)
      边界=获取边界大小排除部分组件(c,/_ABF_Intersect|_ABF_Label/i)
      entities.each {|e|
        if e.is_a?( Sketchup::Edge )
          e.erase!
        end
      }
      bounds=边界[3]
      pts = []
      pts[0] = bounds.corner(一)
      pts[1] = bounds.corner(二)
      pts[2] = bounds.corner(三)
      pts[3] = bounds.corner(四)
      face = entities.add_face(pts)
      # puts "face:#{face}"
      # selection.add face
      # puts "pts:#{pts}"
      # amtf.nil
    end

    def 保留顶面_删除其他边(c)
      trr = c.transformation
      entities=c.entities
      拟删除边=[]
      属于顶面的边s=[]

      # 找顶面
      entities.each {|e|
        if e.is_a?( Sketchup::Face )
          bb = e.bounds
          pt=bb.center
          pt.transform! trr
          if pt.z > -1.mm
            属于顶面的边s=e.edges
            break
          end
        end
      }

      # 删除不属于顶面的边
      entities=c.entities
      entities.each {|e|
        if e.is_a?( Sketchup::Edge )
            if !属于顶面的边s.include?(e)
              拟删除边.push(e)
            end
        end
      }
      # entities.each {|e|
      #   if e.is_a?( Sketchup::Edge )
      #     vertices = e.vertices
      #     vertices.each {|v|
      #       是顶面边线=true
      #       vp=v.position
      #       # puts "vp转换前:#{vp}"
      #       vp.transform! trr
      #       if vp.z.to_f < -3.mm
      #         # puts "vp.z:#{vp.z}"
      #         是顶面边线=false
      #         # e.erase!
      #         # selection.add(e)
      #         拟删除边.push(e)
      #         break
      #       end
      #     }
      #   end
      # }
      拟删除边.each { |e|
        begin
          kk=e.erase!
        rescue => err
         puts err
       end
      }
      # amtf.nil
    end

    def 删除非顶面群组(c,保留通槽组)
      trr = c.transformation
      entities=c.entities
      拟删除群组=[]

      entities.each {|e|
        if e.is_a? Sketchup::ComponentInstance or e.is_a? Sketchup::Group
          组件实例名=e.name
          # puts 组件实例名
          组件tr = trr*e.transformation
          # puts "#{组件实例名}:组件tr.origin:#{组件tr.origin}"
          bb = Geom::BoundingBox.new
          e.entities.each {|en| bb.add(en.bounds) }
          pt=bb.center
          pt.transform! 组件tr
          # puts "组件实例名--#{组件实例名}:bounds.center:#{pt}"
          # amtf.nil
          if pt.z < -1.mm
            # e.erase!
            第一个子e=e.entities[0]
            层名=第一个子e.layer.name
            关键词位置= 层名=~ /-sd-1/i #是ABF形式的通槽
            if 关键词位置!=nil and 保留通槽组
              # 不删除
            else
              拟删除群组.push(e)
            end
          end
        end
      }
      拟删除群组.each { |e|
        kk=e.erase!
      }
      # amtf.nil
    end

    def 删除非顶面边(c)
      trr = c.transformation
      entities=c.entities
      拟删除边=[]
      entities.each {|e|
        if e.is_a?( Sketchup::Edge )
          vertices = e.vertices
          vertices.each {|v|
            是顶面边线=true
            vp=v.position
            # puts "vp转换前:#{vp}"
            vp.transform! trr
            if vp.z.to_f < -3.mm
              # puts "vp.z:#{vp.z}"
              是顶面边线=false
              # e.erase!
              # selection.add(e)
              拟删除边.push(e)
              break
            end
          }
        end
      }
      拟删除边.each { |e|
        begin
          kk=e.erase!
        rescue => err
         puts err
       end
      }
      # amtf.nil
    end

    def 复制面出来删除其他可能的多余边线(c)
      拟处理群组s=[]
      拟临时成组元素s=[]
      拟删除边=[]

      entities=c.entities
      entities.each {|e|
        if e.is_a?( Sketchup::Face )
          拟临时成组元素s.push e
       end
      }

      # 在群组里面用下面这种方式创建群组会有奇怪的问题，在顶层这么做就没问题……
      临时成组 = entities.add_group(拟临时成组元素s.to_a)
      临时成组.name="临时群组"
      # amtf.nil

      # 必须先把面成组了，再来重新遍历
      entities=c.entities
      entities.each {|e|
       if e.is_a?( Sketchup::Edge )
          拟删除边.push(e)
       end
      }

      拟删除边.each { |e|
        begin
          kk=e.erase!
        rescue => err
         puts err
       end
      }
      # amtf.nil
      临时成组.explode
    end

    def 把组件转移到某组件(c,某组件)
      旧组件名=c.name
      puts "某组件"
      puts 某组件
      trr = c.transformation
      # amtf.nil

      c另一个=某组件.entities.add_instance(c.definition,trr)
      # c包裹 = 某组件.add_group(c)
      # amtf.nil
      c另一个.name=旧组件名
      c.erase!
      c=c另一个
      # amtf.nil
      return c
    end

    def 子群组炸开处理_顶层面内部边界处理(c)
       # 找顶层面的内部边界转为子群组
       entities=c.entities
       entities.each {|e|
         if e.is_a?( Sketchup::Face )
           loops = e.loops
           loops.each {|loop|
             if loop.outer?
               # puts "Loop is an outer loop."
             else
               # puts "Loop is not an outer loop."
               edges = loop.edges
              子group = entities.add_group(edges)
              entities子=子group.entities
              #  curve = edges[0].curve
              #  if (curve)
              #    puts "本身就是曲线了，不需要进一步焊接了"
              #  else
              #    puts "是独立的直线，进行焊接"
              #    curves = entities子.weld(entities子.to_a)
              #  end
             end
           }
         end
       }

      #  外围边界不能这么弄
      # 重画法向反了的圆弧(c)

      # 处理群组里面的子群组,比如ABF槽群组，先把顶层元素临时包裹起来，防止自动合并
      拟处理群组s=[]
      拟临时成组元素s=[]
      entities=c.entities
      entities.each {|e|
        if e.is_a? Sketchup::ComponentInstance or e.is_a? Sketchup::Group
          拟处理群组s.push e
        else
          拟临时成组元素s.push e
        end
      }

      # amtf.nil
      临时成组 = entities.add_group(拟临时成组元素s.to_a)
      临时成组.name="临时群组"

      # amtf.nil
      拟处理群组s.each {|e|
        炸开子群组_焊接边线(e)
      }
      临时成组.explode
      # amtf.nil
    end

    def 组件炸开重设原点(c)
      旧组件名=c.name
      # 旧parent=c.parent
      model = Sketchup.active_model
      entities = model.entities
      c包裹 = entities.add_group(c)
      c.explode
      c包裹.name=旧组件名
      c=c包裹
      # c=把组件转移到某组件(c,旧parent)
      return c
    end

    def 炸开子群组_焊接边线(c)
      # 炸开后重新成组，让组的轴平行世界坐标轴,转dxf后才好处理
      # 先包裹再炸开
      c=组件炸开重设原点(c)
      # array = c.explode
      # 炸开后元素s=[]
      # array.each {|e|
      #   # puts "炸开后元素s.type:"
      #   # puts e.typename
      #   if e.is_a?( Sketchup::Edge ) or e.is_a?( Sketchup::Face )
      #     炸开后元素s.push e
      #   end
      #   }
      # entities = Sketchup.active_model.active_entities

      # entities=c.entities
      # entities.each {|e|
      # if e.is_a?( Sketchup::Edge )
      #     curve = e.curve
      #     if (curve)
      #       puts "这是个含曲线的组件，很可能是圆孔，后续不需要炸开等处理……，如果不是圆孔呢，再说"
      #       return
      #     end
      # end
      # }

      # 删除子群组里面的面，为什么？
      面s=[]
      entities=c.entities
      entities.each {|e|
      if e.is_a?( Sketchup::Face )
        面s.push e
      end
      }
      面s.each { |e|
        kk=e.erase!
      }

      重画法向反了的圆弧(c)

      拟焊接曲线s=[]
      entities=c.entities
      entities.each {|e|
      if e.is_a?( Sketchup::Edge )
            curve = e.curve
            line = e.line
            if (curve)
              # puts "curve.typename"
              # puts curve.typename
              if curve.typename!="ArcCurve"
                puts "这是个曲线的组件，但不是圆弧或圆，可能本来就是个整条的曲线，后续不需要焊接处理……，"
                return
               else
                start_angle = curve.start_angle
                end_angle = curve.end_angle
                # puts "start_angle"
                # puts start_angle.radians
                # puts end_angle.radians
                角度差=(end_angle-start_angle).abs.radians
                # puts "角度差"
                # puts 角度差
                if 角度差==360.0
                  # puts "是整圆,不需要焊接"
                else
                  # puts "start_angle"
                  # puts start_angle.radians
                  # puts end_angle.radians
                  # puts "角度差"
                  # puts 角度差
                  拟焊接曲线s.push e
                end
              end
            elsif (line)
              拟焊接曲线s.push e
            else
              # UI.messagebox "Failure"
            end
      end
      }
      curves = entities.weld(拟焊接曲线s)
      puts "焊接后的曲线s:"+curves.to_s

      # amtf.nil
    end

    def 重画法向反了的圆弧(c)
      ees=c.entities
      # puts "ees.count"
      # puts ees.count
      曲线s = []

      for e in ees do
        if e.is_a?( Sketchup::Edge )
          arccurve=e.curve
          if arccurve != nil
            # puts "arccurve"
            # puts arccurve.typename
            if arccurve.typename=="ArcCurve"
              if !曲线s.include?(arccurve)
                puts "找到一个新曲线"
                曲线s.push arccurve
              end
            end
          end
        end
      end

      puts "曲线s.count"
      puts 曲线s.count
      for e in 曲线s do
        # puts e.normal
        arccurve=e
        puts "arccurve"
        puts arccurve
        if arccurve==nil
          next
        end
        centerpoint = arccurve.center
        normal=arccurve.normal.normalize!
        puts normal
        radius = arccurve.radius
        puts radius
        xaxis = arccurve.xaxis
        puts "xaxis"
        puts xaxis.normalize!
        start_angle = arccurve.start_angle
        end_angle = arccurve.end_angle
        puts "start_angle"
        puts start_angle.radians
        puts end_angle.radians

        if normal[2]==-1
          puts "谁的法向反了？👇"
          puts radius

          vector = Geom::Vector3d.new 0,0,1
          normal2 = vector.normalize!
          start_angle2 =-end_angle
          end_angle2 =start_angle
          # start_angle =0.degrees
          # end_angle =30.degrees
          原图层=e.edges[0].layer
          原材质=e.edges[0].material
          for ee in e.edges do
            ee.erase!
          end
          edges = ees.add_arc centerpoint, xaxis, normal2, radius, start_angle2, end_angle2

          for ee in edges do
            ee.layer = 原图层
            ee.material  = 原材质
          end

        end
      end # e in 曲线s do👆
    end

    def 处理图层(c,新图层名,颜色)
      # c.material  = 颜色
      entities=c.entities
      model = Sketchup.active_model
      layers = model.layers
      new_layer = layers.add(新图层名)
      # new_layer.color = 图层颜色
      trr = c.transformation

      entities.each {|e|
        if e.is_a?( Sketchup::Face )
          e.layer = new_layer
          if 颜色=="white"
          else
            e.material  = 颜色
          end

          # 遍历面的内部边界的边线，如果原来没有指定深度sd，则设置为通孔槽sd-1👇
          loops = e.loops
          loops.each {|loop|
            edges = loop.edges
            edges.each{|edge|
              原层名=edge.layer.name
              if loop.outer?
                edge.layer = new_layer
              else
                关键词位置= 原层名=~ /-sd[-\d]+/i
                if 关键词位置!=nil
                  new_layer2 = layers.add("#{新图层名}-amtf-#{原层名}")
                else
                  new_layer2 = layers.add("#{新图层名}-amtf-#{原层名}-sd-1")
                end
                edge.layer = new_layer2
              end
              if 颜色=="white"
              else
                edge.material  = 颜色
              end
            }
          }

        elsif e.is_a? Sketchup::ComponentInstance or e.is_a? Sketchup::Group
          组件实例名=e.name
          e.make_unique
          # if 组件实例名!="_ABF_Label"
            # new_layerbg = layers.add("bao-guo")
            # e.layer = new_layerbg
            entities2=e.entities
            entities2.each {|e2|
              原层名=e2.layer.name
              puts "原图层名："
              puts 原层名
              if 原层名 != "ABF_Label"

              end
              关键词位置= 原层名=~ /DSIde/i
              # p 关键词位置
              # if 关键词位置==nil
                new_layer2 = layers.add("#{新图层名}-amtf-#{原层名}")
                puts "新图层名："
                puts new_layer2.name
                e2.layer = new_layer2
              # end
              # amtf.nil
            }
          # end
          if 组件实例名=="_ABF_Label"
            # e.erase!
            # e.name=@开料主信息
          end
       end
      }

      # puts "拟删除边.count: #{拟删除边.count}"
      # 拟删除边.each { |e|
      #   kk=e.erase!
      # }
      c.explode
      # amtf.nil
    end

    def 生成导出文件夹()
      file=@model.path
      # p @model.path
      路径 = File.dirname(file).freeze
      文件名 = File.basename(file, '.*')
      today = Time.new;
      时间后缀= today.strftime("%Y%m%d_%H%M%S");
      @导出路径="#{路径}/导出-#{文件名}-#{时间后缀}"
      puts "@导出路径: #{@导出路径}"
      Dir.mkdir(@导出路径) unless File.directory?(@导出路径)
      return  @导出路径
    end

    def 删除参考线(c)
      entities=c.entities
      entities.each {|e|
        if e.is_a?( Sketchup::ConstructionLine ) || e.is_a?( Sketchup::ConstructionPoint )
          e.erase!
        end
      }
    end

    def 获取组件面材质名称(群组)
      entities = 群组.entities
      材质=群组.material
      if 材质 !=nil
        材质名称=材质.name
        return 材质名称
      end
      # 材质名称=nil
      # puts "材质名称=#{材质2.name}"
      entities.each {|ee|
        if ee.is_a?( Sketchup::Face )
          材质=ee.material
          if 材质 !=nil
            材质名称=材质.name
            break
          else
            材质名称=nil
          end
        end
      }
      if 材质名称 ==nil
        材质名称="未指定"
      end
      return 材质名称
    end

    def 板材躺平(拟导出对象)
      原点=Geom::Point3d.new(0, 0, 0)
      xaxis=Geom::Vector3d.new 1,0,0
      yaxis=Geom::Vector3d.new 0,1,0
      zaxis=Geom::Vector3d.new 0,0,1

      # 先把标签z轴对齐世界z轴👇遇到过板子是斜的，组件坐标系平行世界坐标系的情况
      entities=拟导出对象.definition.entities
      entities.each {|e|
        if ( e.is_a?( Sketchup::ComponentInstance ) || e.is_a?( Sketchup::Group ))
          组件实例名=e.name
          # puts 组件实例名
          if 组件实例名=="_ABF_Label"###把 _ABF_Label 的原点设置到 世界坐标系原点
            puts "找到定位用的标签了："+组件实例名
            tr = 拟导出对象.transformation*e.transformation
            puts "tr.origin1:"
            puts tr.origin
            vector = tr.origin.vector_to ORIGIN
            tr = Geom::Transformation.translation(vector)

            tr = 拟导出对象.transformation*e.transformation
            标签zaxis=tr.zaxis
            z_anglez = Z_AXIS.angle_between 标签zaxis
            puts "z_anglez:"
            puts z_anglez
            if z_anglez!=0.0
              标签平行z轴 = Z_AXIS.parallel?(标签zaxis)
              if !标签平行z轴
                旋转轴 = 标签zaxis * Z_AXIS
              else
                旋转轴 = X_AXIS
              end
              旋转角度=-z_anglez
              rot = Geom::Transformation.rotation(tr.origin,旋转轴,旋转角度)
              拟导出对象.transform! rot
              # amtf.nil

              tr = 拟导出对象.transformation*e.transformation
              标签zaxis=tr.zaxis
              z_anglez2 = Z_AXIS.angle_between 标签zaxis
              puts "z_anglez2:"
              puts z_anglez2
              if z_anglez2!=0.0
                旋转角度=2*z_anglez
                puts "旋转角度:"
                puts 旋转角度.radians
                rot = Geom::Transformation.rotation(tr.origin,旋转轴,旋转角度)
                拟导出对象.transform! rot
                # amtf.nil

                tr = 拟导出对象.transformation*e.transformation
                标签zaxis=tr.zaxis
                z_anglez3 = Z_AXIS.angle_between 标签zaxis
                puts "转动后z_anglez3:"
                puts z_anglez3
                puts z_anglez3.radians
                if z_anglez3!=0.0
                  UI.messagebox "标签的z轴线没法转到和全局z轴平行，太难了，只能撂挑子了 ！"
                  amtf.nil
                end
              end
            end# 以上对齐z轴👆


            tr = 拟导出对象.transformation*e.transformation
            标签xaxis=tr.xaxis
            旋转轴 = Z_AXIS
            # 原来你的夹角，是不会区分逆时针和顺时针的，不会有负值，也不会超过180°
            x_anglex = 标签xaxis.angle_between X_AXIS
            puts "x_anglex:"
            puts x_anglex
            puts x_anglex.radians
            if x_anglex!=0.0
              旋转角度=-x_anglex
              rot = Geom::Transformation.rotation(tr.origin,旋转轴,旋转角度)
              拟导出对象.transform! rot

              tr = 拟导出对象.transformation*e.transformation
              标签xaxis=tr.xaxis
              x_anglex2 = 标签xaxis.angle_between X_AXIS
              puts "转动后x_anglex2:"
              puts x_anglex2
              puts x_anglex2.radians
              if x_anglex2!=0.0
                旋转角度=2*x_anglex
                puts "旋转角度:"
                puts 旋转角度.radians
                rot = Geom::Transformation.rotation(tr.origin,旋转轴,旋转角度)
                拟导出对象.transform! rot

                tr = 拟导出对象.transformation*e.transformation
                标签xaxis=tr.xaxis
                x_anglex3 = 标签xaxis.angle_between X_AXIS
                puts "转动后x_anglex3:"
                puts x_anglex3
                puts x_anglex3.radians
                if x_anglex3!=0.0
                  UI.messagebox "标签的x轴线没法转到和全局x轴平行，太难了，只能撂挑子了 ！"
                  amtf.nil
                end
              end
            end# 以上对齐x轴👆

            # amtf.nil
            break
            puts "上方的break如果没生效，你就会看到我！"
          end
        end
      }

      # 炸开后重新成组，让组的轴平行世界坐标轴
      # 原组件名=拟导出对象.name
      # group新 = entities.add_group(拟导出对象)
      # 拟导出对象.explode

      # group新.name=原组件名
      # 拟导出对象 = group新
      拟导出对象=组件炸开重设原点(拟导出对象)

      point1 = Geom::Point3d.new(0, 0, 0)
      x = Geom::Vector3d.new(1, 0, 0)
      y = Geom::Vector3d.new(0, 1, 0)
      z = Geom::Vector3d.new(0, 0, 1)
      tr2 = Geom::Transformation.new(x,y,z,point1)
      拟导出对象.transformation = tr2
      return 拟导出对象

      # 判断标签方向👇，上面如果已经能够成功对齐标签，下面就不需要折腾了
      entities=拟导出对象.definition.entities
      entities.each {|e|
        if ( e.is_a?( Sketchup::ComponentInstance ) || e.is_a?( Sketchup::Group ))
          组件实例名=e.name
          # puts 组件实例名
          if 组件实例名=="_ABF_Label"###把 _ABF_Label 的原点设置到 世界坐标系原点
            puts "找到定位用的标签了："+组件实例名
            tr = e.transformation
            tr2 = tr.inverse
            拟导出对象.transformation = tr2
            边界大小2=获取边界大小(拟导出对象)
            # amtf.nil
            x缩放=边界大小1[0]/边界大小2[0]
            puts "x缩放:#{x缩放}"
            y缩放=边界大小1[1]/边界大小2[1]
            puts "y缩放:#{y缩放}"
            z缩放=边界大小1[2]/边界大小2[2]
            puts "z缩放:#{z缩放}"
            # tr3 = Geom::Transformation.scaling(x缩放,y缩放,z缩放)

            标签xaxis=tr2.xaxis
            x_anglex = xaxis.angle_between 标签xaxis
            puts "标签xaxis 与 x轴夹角:#{x_anglex}==#{x_anglex.radians}"
            x_平行x轴 = xaxis.parallel?(标签xaxis)
            puts "x_平行x轴？:#{x_平行x轴}"
            x_angley = yaxis.angle_between 标签xaxis
            puts "标签xaxis 与 y轴夹角:#{x_angley}==#{x_angley.radians}"
            x_平行y轴 = yaxis.parallel?(标签xaxis)
            puts "x_平行y轴？:#{x_平行y轴}"
            x_anglez = zaxis.angle_between 标签xaxis
            puts "标签xaxis 与 z轴夹角:#{x_anglez}==#{x_anglez.radians}"
            x_平行z轴 = zaxis.parallel?(标签xaxis)
            puts "x_平行z轴:#{x_平行z轴}"
            # amtf.nil

            拟导出对象yaxis=tr2.yaxis
            y_angley = yaxis.angle_between 拟导出对象yaxis
            # puts "拟导出对象yaxis 与 y轴夹角:#{y_angley}==#{y_angley.radians}"
            y_平行x轴 = yaxis.parallel?(拟导出对象yaxis)
            # puts "y_平行x轴？:#{y_平行x轴}"
            y_angley = yaxis.angle_between 拟导出对象yaxis
            # puts "拟导出对象yaxis 与 y轴夹角:#{y_angley}==#{y_angley.radians}"
            y_平行y轴 = yaxis.parallel?(拟导出对象yaxis)
            # puts "y_平行y轴？:#{y_平行y轴}"
            y_anglez = zaxis.angle_between 拟导出对象yaxis
            # puts "拟导出对象yaxis 与 z轴夹角:#{y_anglez}==#{y_anglez.radians}"
            y_平行z轴 = zaxis.parallel?(拟导出对象yaxis)
            # puts "y_平行z轴:#{y_平行z轴}"
            # amtf.nil
           if x_平行x轴
            绝对x缩放=x缩放
            if y_平行y轴
              绝对y缩放=y缩放
              绝对z缩放=z缩放
            else
              绝对y缩放=z缩放
              绝对z缩放=y缩放
            end
           elsif x_平行y轴
            绝对y缩放=x缩放
            if y_平行z轴
              绝对x缩放=z缩放
              绝对z缩放=y缩放
            else
              绝对x缩放=y缩放
              绝对z缩放=z缩放
            end
           else #x_平行z轴
            绝对z缩放=x缩放
            if y_平行x轴
              绝对x缩放=y缩放
              绝对y缩放=z缩放
            else
              绝对x缩放=z缩放
              绝对y缩放=y缩放
            end
           end
            # tr3 = Geom::Transformation.scaling(1.968503937007874,1.968503937007874,1.0000000000000004)
            puts "绝对x缩放:#{绝对x缩放}"
            puts "绝对y缩放:#{绝对y缩放}"
            puts "绝对z缩放:#{绝对z缩放}"
            tr3 = Geom::Transformation.scaling(绝对x缩放,绝对y缩放,绝对z缩放)
            拟导出对象.transform! tr3
            # amtf.nil
            return 拟导出对象
            # break
          end
        end#如果是组件👆
      }
    end


    def 获取转换信息()
      设置常用对象
      信息h=Hash[]

      选择的ents=[]
      if @selection.count == 0
        UI.messagebox "请选择一个 组件 或者 群组 ！"
        return false
      else
        # entities=@entities
        entities=@selection
        entities.each {|e|
          if e.is_a? Sketchup::ComponentInstance or e.is_a? Sketchup::Group
            组件定义名=e.definition.name
            组件实例名=e.name
            组件加实例名=组件定义名+"+"+组件实例名
            puts 组件加实例名
            id=组件加实例名
            信息h[id]=Hash[]
            # puts e.transformation.to_a.to_s
            tr=e.transformation
            str4x4 = tr.to_a.each_slice(4).inject { |str, row| "#{str}\r\n#{row}" }
            puts str4x4
            信息h[id]["transformation"]=str4x4

            point2 = tr.origin
            puts "origin: #{point2.to_s}"
            信息h[id]["原点"]=point2.to_s
            x = tr.xaxis
            puts "xaxis: #{x.to_s}"
            信息h[id]["x轴"]=x.to_s
            y = tr.yaxis
            puts "yaxis: #{y.to_s}"
            信息h[id]["y轴"]=y.to_s

            z = tr.zaxis
            puts "zaxis: #{z.to_s}"
            信息h[id]["z轴"]=z.to_s

            边界大小=获取边界大小(e)
            信息h[id]["x尺寸"]=边界大小[0].to_l
            信息h[id]["y尺寸"]=边界大小[1].to_l
            信息h[id]["z尺寸"]=边界大小[2].to_l
          end
        }
      end

      # puts 信息h.to_a.to_s
      puts 信息h.to_json
      # 信息h.each{|k,v|
      #   angle = vector2.angle_between(v).radians
      #   puts "组件id: #{k}"

      #   v.each{|kk,vv|
      #     单项="#{k}: #{vv}"
      #     angle = vector2.angle_between(v).radians
      #     puts "组件id: #{k}"

      #   }
      # }
    end

    def gp测试
      设置常用对象
      if @selection.count == 0
        UI.messagebox "请先选择一个 拟导出对象 ！"
      else
        对象=@selection[0]
      end
      entities = 对象.entities
      if (entities)
        UI.messagebox entities
      else
        UI.messagebox "Failure"
      end
    end
  end#class
end # module amtf_su
